# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: leon

from coin.base.book.aggregated_book_builder import AggregatedBookBuilder
from coin.base.book.book_builder_base import BookBuilderBase
from coin.base.book.aggregated_book_builder import BookUpdateSide


class MultipleBookBuilderWrapper(object):
  def __init__(self, original_book: BookBuilderBase, aggregated_ticksizes):
    self._original_book = original_book
    self._aggregated_books = {}
    assert isinstance(aggregated_ticksizes, list)
    for ticksize in aggregated_ticksizes:
      self._aggregated_books[ticksize] = \
          AggregatedBookBuilder(original_book, ticksize)

  def get_original_book(self):
    return self._original_book

  def get_aggregated_book(self, ticksize):
    return self._aggregated_books[ticksize]

  # To rebuild all aggregated books based on latest original book.
  def generate_aggregated_books(self):
    for agg_book in self._aggregated_books.values():
      agg_book.generate_aggregated_book(BookUpdateSide.BID)
      agg_book.generate_aggregated_book(BookUpdateSide.ASK)

  def update_aggregated_books(self, update_side: BookUpdateSide, price, qty):
    for agg_book in self._aggregated_books.values():
      agg_book.update_aggregated_book(update_side, price, qty)

  # The followings are fast forward original book functions.
  @property
  def timestamp(self):
    return self._original_book.timestamp

  @property
  def symbol(self):
    return self._original_book.symbol

  @property
  def exchange(self):
    return self._original_book.exchange

  def update_timestamp(self, timestamp):
    self._original_book.fetched_timestamp = timestamp

  def update_exchange_timestamp(self, timestamp):
    self._original_book.exchange_timestamp = timestamp

  def bid0(self):
    return self._original_book.bid0()

  def ask0(self):
    return self._original_book.ask0()

  def iteritems_ask(self):
    return self._original_book.iteritems_ask()

  def iteritems_bid(self):
    return self._original_book.iteritems_bid()

  def get_accumulated_bid_qty(self, from_price, to_price):
    return self._original_book.get_accumulated_bid_qty(from_price, to_price)

  def iter_bid_book(self, num_level, step_price, min_unit=1.e-8):
    return self._original_book.iter_bid_book(num_level, step_price, min_unit)

  def get_accumulated_ask_qty(self, from_price, to_price):
    return self._original_book.get_accumulated_ask_qty(from_price, to_price)

  def iter_ask_book(self, num_level, step_price, min_unit=1.e-8):
    return self._original_book.iter_ask_book(num_level, step_price, min_unit)

  def get_notional_bids_by_qty(self, qty):
    return self._original_book.get_notional_bids_by_qty(qty)

  def get_notional_asks_by_qty(self, qty):
    return self._original_book.get_notional_asks_by_qty(qty)

  def get_notional_bids_by_amt(self, price):
    return self._original_book.get_notional_bids_by_amt(price)

  def get_notional_asks_by_amt(self, price):
    return self._original_book.get_notional_asks_by_amt(price)

  def get_bid_price_by_amount(self, amount):
    return self._original_book.get_bid_price_by_amount(amount)

  def get_ask_price_by_amount(self, amount):
    return self._original_book.get_ask_price_by_amount(amount)

  def clear(self):
    for agg_book in self._aggregated_books.values():
      agg_book.clear()
